//////////////////////////////////////////////////////////////////////////
#pragma once
#pragma managed
//////////////////////////////////////////////////////////////////////////
using namespace System::Runtime::InteropServices;
//////////////////////////////////////////////////////////////////////////
NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
public interface class IColor
{
	// CvScalar Scale { T get(); void set(T value); }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Gray : public IColor
{
private:
	T intensity;

public:
	property T Intensity { T get() { return intensity; } void set(T value) { intensity = value; } }

public:
	Gray(T _intensity) : intensity(_intensity) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Bgr : public IColor
{
private:
	T b;
	T g;
	T r;

public:
	property T B { T get() { return b; } void set(T value) { b = value; } }
	property T G { T get() { return g; } void set(T value) { g = value; } }
	property T R { T get() { return r; } void set(T value) { r = value; } }

public:
	Bgr(T _b, T _g, T _r) : b(_b), g(_g), r(_r) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Bgra : public IColor
{
private:
	T b;
	T g;
	T r;
	T a;

public:
	property T B { T get() { return b; } void set(T value) { b = value; } }
	property T G { T get() { return g; } void set(T value) { g = value; } }
	property T R { T get() { return r; } void set(T value) { r = value; } }
	property T A { T get() { return a; } void set(T value) { a = value; } }

public:
	Bgra(T _b, T _g, T _r, T _a) : b(_b), g(_g), r(_r), a(_a) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Rgb : public IColor
{
private:
	T r;
	T g;
	T b;

public:
	property T B { T get() { return b; } void set(T value) { b = value; } }
	property T G { T get() { return g; } void set(T value) { g = value; } }
	property T R { T get() { return r; } void set(T value) { r = value; } }

public:
	Rgb(T _r, T _g, T _b) : b(_b), g(_g), r(_r) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Rgba : public IColor
{
private:
	T r;
	T g;
	T b;
	T a;

public:
	property T B { T get() { return b; } void set(T value) { b = value; } }
	property T G { T get() { return g; } void set(T value) { g = value; } }
	property T R { T get() { return r; } void set(T value) { r = value; } }
	property T A { T get() { return a; } void set(T value) { a = value; } }

public:
	Rgba(T _r, T _g, T _b, T _a) : b(_b), g(_g), r(_r), a(_a) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Xyz : public IColor
{
private:
	T x;
	T y;
	T z;

public:
	property T X { T get() { return x; } void set(T value) { x = value; } }
	property T Y { T get() { return y; } void set(T value) { y = value; } }
	property T Z { T get() { return z; } void set(T value) { z = value; } }

public:
	Xyz(T _x, T _y, T _z) : x(_x), y(_y), z(_z) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct YCrCb : public IColor
{
private:
	T y;
	T cr;
	T cb;

public:
	property T Y { T get() { return y; } void set(T value) { y = value; } }
	property T Cr { T get() { return cr; } void set(T value) { cr = value; } }
	property T Cb { T get() { return cb; } void set(T value) { cb = value; } }

public:
	YCrCb(T _y, T _cr, T _cb) : y(_y), cr(_cr), cb(_cb) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Hsv : public IColor
{
private:
	T h;
	T s;
	T v;

public:
	property T H { T get() { return h; } void set(T value) { h = value; } }
	property T S { T get() { return s; } void set(T value) { s = value; } }
	property T V { T get() { return v; } void set(T value) { v = value; } }

public:
	Hsv(T _h, T _s, T _v) : h(_h), s(_s), v(_v) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Lab : public IColor
{
private:
	T l;
	T a;
	T b;

public:
	property T L { T get() { return l; } void set(T value) { l = value; } }
	property T A { T get() { return a; } void set(T value) { a = value; } }
	property T B { T get() { return b; } void set(T value) { b = value; } }

public:
	Lab(T _l, T _a, T _b) : l(_l), a(_a), b(_b) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack = 1)]
public value struct Luv : public IColor
{
private:
	T l;
	T u;
	T v;

public:
	property T L { T get() { return l; } void set(T value) { l = value; } }
	property T U { T get() { return u; } void set(T value) { u = value; } }
	property T V { T get() { return v; } void set(T value) { v = value; } }

public:
	Luv(T _l, T _u, T _v) : l(_l), u(_u), v(_v) { }
};

generic<typename T> where T : value struct
[StructLayoutAttribute(LayoutKind::Sequential, Pack=1)]
public value struct Hls : public IColor
{
private:
	T h;
	T l;
	T s;

public:
	property T H { T get() { return h; } void set(T value) { h = value; } }
	property T L { T get() { return l; } void set(T value) { l = value; } }
	property T S { T get() { return s; } void set(T value) { s = value; } }

public:
	Hls(T _h, T _l, T _s) : h(_h), l(_l), s(_s) { }
};
//////////////////////////////////////////////////////////////////////////
NAMESPACE_END
//////////////////////////////////////////////////////////////////////////